; tuques - alternative version #2 including a scroll-text
; 141 byte intro for FEZ which is crocheted into tuques
; code by sy2002 on Dec, 30 2013
;
; inspired by fr29b by ByTeGeiZ
; 	http://www.pouet.net/prod.php?which=5028
;	http://www.codejuggle.dj/29-byte-dos-intro-called-fr29b/
;
; more about the tuques project
;	http://fezbook.de/tuques
;
; about the tuque that was crocheted using this demo
;	http://fezbook.de/0xDem01
;
; compiles to a 16-bit DOS .com executable using NASM (http://www.nasm.us/)
; using the following settings: nasm -f bin -o tuques2.com tuques2.asm
;

org	0x100

; source code section
section .text

	; set 320*200 graphics mode with 256 colors
	mov		al, 0x13
	int		0x10               
	
	; use BIOS to print the string (BIOS knows how to paint text
	; also in graphics modes like the 13h mode)
	mov		ax, ds
	mov		es, ax
	mov		bp, text_data
	mov		ax, 0x1301			; ah = $13 = write string; al = move cursor
	mov		bx, 00001101b		; bh = video page = 0; bl = char attribute
	mov		cx, text_size		; length of string
	xor		dx, dx				; dh = dl = 0 = initial xy-pos of text
	int		0x10 				; call BIOS

	; remember VGA RAM start adress
	mov		ax, 0xA000
	mov		es, ax

	; start position of the scroll text is top left
	xor		bp, bp
		
	; copy text as bitpattern to RAM buffer
	; (this is later used for the repeated copies)
	xor		di, di
	mov		cx, gfx_size
store_bitpattern:
	mov		al, byte [es:di]
	mov		byte [gfx_buffer+di], al
	inc		di
	loop	store_bitpattern
		
	; main PLASMA routine
next_box:
	rdtsc						; read time stamp counter
	xchg	ax, di				; use it as random offset to vga buffer
	mov		cx, 0x8c			; use a 140*140 box
    
next_line:
	mov     bx, 0x8c
 
next_pixel:
	inc     byte [es:bx+di]       ; increase color index in this box
	or      byte [es:bx+di], 0x80 ; ensure upper bit is set
	dec     bx
	jnz     next_pixel
	add     di, 0x140			; add 320 = point to next line
	loop    next_line

	; delete previously painted text at old xy-position (bp)
	dec		byte [paint_mode]	; equals paint_mode = 0
	call	text_display

	; paint next next at a new xy-position (bp)
	inc		bp
	inc		byte [paint_mode]	; equals paint_mode = 1
	call	text_display

	; repeat endlessly        
	jmp     next_box

	; paint_mode = 1: add, paint_mode = 0: sub
text_display:
	xor		si, si
	mov		di, bp
	mov		cx, gfx_size
loop_restore_add:
	mov		al, byte [gfx_buffer+si]
	cmp		byte [paint_mode], 1
	jne		loop_restore_sub
	add		byte [es:di], al
	or		byte [es:di], 0x80
	jmp		loop_restore_cont
loop_restore_sub:
	sub		byte [es:di], al
loop_restore_cont:
	inc		si
	inc		di
	loop	loop_restore_add
	ret
    	
; data which is compiled to the .com file			
section .data

paint_mode	db		1					; toggles between 1 and 0
text_size	equ 	16
text_data	db		"tuque FEZ sy2002"	; may be one line of text at maximum 

; uninitialized RAM data
section .bss

gfx_size	equ		320*8		; size of one text line on the screen
gfx_buffer	resb 	gfx_size	; amount of bytes
